using System;

namespace NeosSDI.Core.Unity
{
    /// <summary>
    /// Singleton pour la fabrique de L'IOC
    /// </summary>
    /// <remarks>
    /// L'inversion de contrôle (Inversion of Control, IoC) est un patron d'architecture commun à tous les frameworks (ou cadre de développement et d'exécution). 
    /// Il fonctionne selon le principe que le flot d'exécution d'un logiciel n'est plus sous le contrôle direct de l'application elle-même mais du framework ou de la 
    /// couche logicielle sous-jacente.
    /// L'inversion de contrôle est un terme générique. 
    /// Selon la problématique, il existe différentes formes, ou représentation d'IoC. 
    /// Le plus connu étant l'injection de dépendances (dependency injection) qui est un patron de conception permettant, en programmation orientée objet, 
    /// de découpler les dépendances entre objets. 
    /// </remarks>
    public sealed class IoCFactory : IDisposable
    {
        #region Singleton

        static readonly IoCFactory instance = new IoCFactory();

        /// <summary>
        /// Get singleton instance of IoCFactory
        /// </summary>
        public static IoCFactory Instance
        {
            get
            {
                return instance;
            }
        }

        #endregion

        readonly IContainer _currentContainer;

        /// <summary>
        /// Get current configured IContainer
        /// <remarks>
        /// At this moment only IoCUnityContainer exists
        /// </remarks>
        /// </summary>
        public IContainer CurrentContainer
        {
            get
            {
                return _currentContainer;
            }
        }

        #region ctor

        /// <summary>
        /// Conxtructeur par défaut
        /// </summary>
        IoCFactory()
        {
            _currentContainer = new IoCUnityContainer();
        }

        #endregion

        #region IDisposable

        /// <summary>
        /// detect if alreadey disposed
        /// </summary>
        private bool _disposed;

        /// <summary>
        /// Destructeur
        /// </summary>
        ~IoCFactory()
        {
            Dispose(false);
        }

        /// <summary>
        /// Fonction de ralachement de l'objet
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Fonction de ralachement de l'objet
        /// </summary>
        /// <param name="disposing">true si l'objet doit être effectivement relaché, false dans le cas contraire</param>
        private void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    if (_currentContainer != null)
                        _currentContainer.Dispose();
                }
            }
            _disposed = true;

        }
        #endregion
    }
}
